mDot processor with ROHM sensor board on UDK2.

Dependencies:   MbedJSONValue libmDot mbed-rtos mbed

Fork of VVV_MultiTech_Dragonfly_ATT_Dallas by Paul Jaeger

Revision:
8:720595aa7bfd
Parent:
7:dd550a829ece
Child:
9:10082fc85d18
--- a/main.cpp	Fri Dec 11 16:00:08 2015 +0000
+++ b/main.cpp	Fri Feb 26 02:42:23 2016 +0000
@@ -1,13 +1,16 @@
 /*************************************************************************
+ * Originally this was a 
  * Dragonfly Example program for 2015 AT&T Government Solutions Hackathon
  *
+ * This is in process of being convertered to a mDot processor.  mDot has a
+ * limited set of IO that are available to the ROHM board.  Most of the
+ * Sensors will be used but the ones that can't have been commented out.
+ *
  * 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)
- *   - Seeed Studio Base Shield
- *   - Grove moisture sensor (to connect to Base Shield)
- *   - Grove button (to connect to Base Shield)
+ *   - MultiTech mDot with a LoRa radio
+ *   - Seeed Studio Base Shield to elevate the ROHM board connectors away from mDOt
  *   - MEMs Inertial and Environmental Nucleo Expansion board (LSM6DS0
  *     3-axis accelerometer + 3-axis gyroscope, LIS3MDL 3-axis
  *     magnetometer, HTS221 humidity and temperature sensor and LPS25HB
@@ -17,9 +20,8 @@
  *   - reads data from all sensors on MEMs board and moisture sensor on a
  *     periodic basis
  *   - prints all sensor data to debug port on a periodic basis
- *   - optionally send a SMS containing sensor data when the Grove Button
- *     is pushed
- *       - you need to set the "phone_number" field
+ *   - optionally sends LoRa sensor data when the timer expires
+ *        THis needs to be written yet.
  *   - optionally sends sensor data to AT&T M2X cloud platform (user must
  *     create own M2X account and configure a device)
  *       - you need to set the "m2x_api_key" field and the "m2x_device_id"
@@ -28,27 +30,22 @@
  *         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"
+ *   - Seat the mDot on the UDK2 board
  *   - Stack the Base Shield on the UDK2 Arduino headers
- *   - Connect the Grove button to the D8 socket on the Base Shield
- *   - Connect the Grove moisture sensor to the A0 socket on the Base
- *     Shield
  *   - Make sure the reference voltage selector switch (next to the A0
- *     socket) is switched to 5V so you get accurate analog readings
+ *     socket) is switched to 3.3V so you don't blow the mDot analog converter
+  *    accuracy will suffer as a result when compared to 5V.
  *   - 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)
+ *   - Plug a micro USB cable away from the multiple LED String
  *
  * 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.
+   This Program will enable to Multi-Tech mDot platform to utilize ROHM's Multi-sensor Shield Board.
+   This program will initialize most of the 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:
@@ -61,29 +58,21 @@
 
 
 #include "mbed.h"
-#include "mtsas.h"
 #include "MbedJSONValue.h"
-#include "HTTPJson.h"
+// #include "HTTPJson.h"
 #include <string>
 
+//  added the following help files for a mDot not required for Dragonfly.
+#include "mDot.h"
+#include "MTSLog.h"
+#include <vector>
+#include <algorithm>
+#include "rtos.h"
+
+
 // Debug serial port
 static Serial debug(USBTX, USBRX);
 
-// MTSSerialFlowControl - serial link between processor and radio
-static MTSSerialFlowControl* io;
-
-// Cellular - radio object for cellular operations (SMS, TCP, etc)
-Cellular* radio;
-
-// APN associated with SIM card
-// this APN should work for the AT&T SIM that came with your Dragonfly
-//static const std::string apn = "";
-static const std::string apn = "";
-
-// Phone number to send SMS messages to
-// just change the x digits - the 1 needs to stay!
-static const std::string phone_number = "1xxxxxxxxxx";
-
 // see https://m2x.att.com/developer/documentation/v2/overview for M2X API documentation
 // M2X device ID
 static const std::string m2x_device_id = "";
@@ -93,8 +82,8 @@
 
 // set to true if you want to post to the cloud
 // you need to have you M2X account set up properly for this to work?
-//bool do_cloud_post = false;
-bool do_cloud_post = true;
+bool do_cloud_post = false;
+//bool do_cloud_post = true;
 
 std::string url = "http://api-m2x.att.com/v2/devices/" + m2x_device_id + "/update";
 
@@ -119,15 +108,13 @@
 int debug_baud = 115200;
 
 
-
-
 /****************************************************************************************************
 
  ****************************************************************************************************/
 
 //Macros for checking each of the different Sensor Devices
 #define AnalogTemp  //BDE0600
-#define AnalogUV    //ML8511
+// #define AnalogUV    //ML8511  // analog pin A4 on Arduino connector is not connected to the mDot on the UDK.
 #define HallSensor  //BU52011
 #define RPR0521     //RPR0521
 #define KMX62       //KMX61, Accel/Mag         
@@ -145,20 +132,20 @@
 
 //Define Sensor Variables
 #ifdef AnalogTemp
-AnalogIn    BDE0600_Temp(PC_4); //Mapped to A2
+AnalogIn    BDE0600_Temp(PC_1); //Mapped to A2  pin 15 on the mDot
 uint16_t    BDE0600_Temp_value;
 float       BDE0600_output;
 #endif
 
-#ifdef AnalogUV
-AnalogIn    ML8511_UV(PC_1);    //Mapped to A4
-uint16_t    ML8511_UV_value;
-float       ML8511_output;
-#endif
+//#ifdef AnalogUV                // analog pin A4 on Arduino connector is not connected to the mDot on the UDK.
+//AnalogIn    ML8511_UV(PA_7);    //Mapped to A4  not a pin routed on the UDK to the mDot
+//uint16_t    ML8511_UV_value;
+//float       ML8511_output;
+//#endif
 
 #ifdef HallSensor
-DigitalIn   Hall_GPIO0(PC_8);
-DigitalIn   Hall_GPIO1(PB_5);
+DigitalIn   Hall_GPIO0(PA_4);       // assigned to D10 on Arduino, mapped to pin 17 on mDot
+DigitalIn   Hall_GPIO1(PA_7);       // assigned to D11 on Arduino, mapped to pin 11 on mDot
 int         Hall_Return1;
 int         Hall_Return0;
 int32_t     Hall_Return[2];
@@ -273,7 +260,7 @@
  ****************************************************************************************************/
 bool init_mtsas();
 void ReadAnalogTemp();
-void ReadAnalogUV ();
+// void ReadAnalogUV ();   // analog pin A4 on Arduino connector is not connected to the mDot on the UDK.
 void ReadHallSensor ();
 void ReadCOLOR ();
 void ReadRPR0521_ALS ();
@@ -282,12 +269,18 @@
 void ReadPressure ();
 void ReadKX022();
 
+// these options must match the settings on your Conduit
+// uncomment the following lines and edit their values to match your configuration
+static std::string config_network_name = "Arrow123";
+static std::string config_network_pass = "Arrow123";
+static uint8_t config_frequency_sub_band = 1;
+
 /****************************************************************************************************
 // main
  ****************************************************************************************************/
 int main()
 {
-    mts::MTSLog::setLogLevel(mts::MTSLog::TRACE_LEVEL);
+    mts::MTSLog::setLogLevel(mts::MTSLog::TRACE_LEVEL);  //NONE_, FATAL_, ERROR_, WARNING_, INFO_, DEBUG_, TRACE_
     debug.baud(debug_baud);
     logInfo("starting...");
 
@@ -328,19 +321,83 @@
 #endif
 //End I2C Initialization Section **********************************************************
 
+//Initialize the mDot  ********************************************************************
+    int32_t ret;
+    mDot* dot;
+    std::vector<uint8_t> data;
+    std::string data_str = "hello! Jeff";
+    
+    // get a mDot handle
+    dot = mDot::getInstance();
+    
+    // print library version information
+    logInfo("version: %s", dot->getId().c_str());
 
-// Initialization Radio Section **********************************************************
+    //*******************************************
+    // configuration
+    //*******************************************
+    // reset to default config so we know what state we're in
+    dot->resetConfig();
+    
+    dot->setLogLevel(mts::MTSLog::TRACE_LEVEL);  //INFO_LEVEL
 
-    radio_ok = init_mtsas();
-    if (! radio_ok)
-        logError("MTSAS init failed");
-    else
-        logInfo("MTSAS is ok");
+    // set up the mDot with our network information: frequency sub band, network name, and network password
+    // these can all be saved in NVM so they don't need to be set every time - see mDot::saveConfig()
+    
+    // frequency sub band is only applicable in the 915 (US) frequency band
+    // if using a MultiTech Conduit gateway, use the same sub band as your Conduit (1-8) - the mDot will use the 8 channels in that sub band
+    // if using a gateway that supports all 64 channels, use sub band 0 - the mDot will use all 64 channels
+    logInfo("setting frequency sub band");
+    if ((ret = dot->setFrequencySubBand(config_frequency_sub_band)) != mDot::MDOT_OK) {
+        logError("failed to set frequency sub band %d:%s", ret, mDot::getReturnCodeString(ret).c_str());
+    }
+    
+    logInfo("setting network name");
+    if ((ret = dot->setNetworkName(config_network_name)) != mDot::MDOT_OK) {
+        logError("failed to set network name %d:%s", ret, mDot::getReturnCodeString(ret).c_str());
+    }
+    
+    logInfo("setting network password");
+    if ((ret = dot->setNetworkPassphrase(config_network_pass)) != mDot::MDOT_OK) {
+        logError("failed to set network password %d:%s", ret, mDot::getReturnCodeString(ret).c_str());
+    }
+    
+    // a higher spreading factor allows for longer range but lower throughput
+    // in the 915 (US) frequency band, spreading factors 7 - 10 are available
+    // in the 868 (EU) frequency band, spreading factors 7 - 12 are available
+    logInfo("setting TX spreading factor");
+    if ((ret = dot->setTxDataRate(mDot::SF_10)) != mDot::MDOT_OK) {
+        logError("failed to set TX datarate %d:%s", ret, mDot::getReturnCodeString(ret).c_str());
+    }
+    
+    // request receive confirmation of packets from the gateway
+    logInfo("enabling ACKs");
+    if ((ret = dot->setAck(1)) != mDot::MDOT_OK) {
+        logError("failed to enable ACKs %d:%s", ret, mDot::getReturnCodeString(ret).c_str());
+    }
+    
+    // save this configuration to the mDot's NVM
+    logInfo("saving config");
+    if (! dot->saveConfig()) {
+        logError("failed to save configuration");
+    }
+    //*******************************************
+    // end of configuration
+    //*******************************************
 
-//End Radio Initialization Section **********************************************************
+    // attempt to join the network
+    logInfo("joining network");
+    while ((ret = dot->joinNetwork()) != mDot::MDOT_OK) {
+        logError("failed to join network %d:%s", ret, mDot::getReturnCodeString(ret).c_str());
+        // in the 868 (EU) frequency band, we need to wait until another channel is available before transmitting again
+        osDelay(std::max((uint32_t)1000, (uint32_t)dot->getNextTxMs()));
+    }
 
-//    button.fall(&button_irq);
+    // format data for sending to the gateway
+    for (std::string::iterator it = data_str.begin(); it != data_str.end(); it++)
+        data.push_back((uint8_t) *it);
 
+// END Initialization of mDot  ******************************************************************
 
     Timer thpm_timer;
     thpm_timer.start();         // Timer data is set in the Variable seciton see misc variables    Timer motion_timer;
@@ -353,6 +410,7 @@
     Timer sms_timer;
     sms_timer.start();
 #endif
+
 #ifdef Web
     Timer post_timer;
     post_timer.start();
@@ -364,9 +422,9 @@
             ReadAnalogTemp ();
 #endif
 
-#ifdef AnalogUV
-            ReadAnalogUV ();
-#endif
+//#ifdef AnalogUV       // analog pin A4 on Arduino connector is not connected to the mDot on the UDK.
+//            ReadAnalogUV ();
+//#endif
 
 #ifdef HallSensor
             ReadHallSensor ();
@@ -402,7 +460,7 @@
             logDebug("%s", wall_of_dash);
             logDebug("SENSOR DATA");
             logDebug("temperature: %0.2f C", BM1383[0]);
-            logDebug("analog uv: %.1f mW/cm2", ML8511_output);
+//            logDebug("analog uv: %.1f mW/cm2", ML8511_output);  // analog pin A4 on Arduino connector is not connected to the mDot on the UDK.
             logDebug("ambient Light  %0.3f", RPR0521_ALS[0]);
             logDebug("proximity count  %0.3f", RPR0521_ALS[1]);
             logDebug("hall effect: South %d\t North %d",  Hall_Return[0],Hall_Return[1]);
@@ -421,14 +479,14 @@
             sms_timer.reset();
             logInfo("SMS Send Routine");
 printf("  In sms routine \r\n");
-            if (radio_ok) {
-                MbedJSONValue sms_json;
-                string sms_str;
-
+//            if (radio_ok) {
+//                MbedJSONValue sms_json;
+//                string sms_str;
+//
 //                sms_json["temp_C"] = BDE0600_output;
 //                sms_json["UV"] = ML8511_output;
-                sms_json["Ambient Light"] = RPR0521_ALS[0];
-                sms_json["Prox"]      = RPR0521_ALS[1];
+//                sms_json["Ambient Light"] = RPR0521_ALS[0];
+//                sms_json["Prox"]      = RPR0521_ALS[1];
 //                sms_json["pressure_hPa"] = BM1383[1];
 //                sms_json["mag_mgauss"]["x"] = MEMS_Mag[0];
 //                sms_json["mag_mgauss"]["y"] = MEMS_Mag[1];
@@ -439,81 +497,63 @@
 //                sms_json["Red"]   = BH1745[0];
 //                sms_json["Green"] = BH1745[1];
 //                sms_json["Blue"]  = BH1745[2];
-
-                sms_str = "SENSOR DATA:\n";
-                sms_str += sms_json.serialize();
-
-                logDebug("sending SMS to %s:\r\n%s", phone_number.c_str(), sms_str.c_str());
-                Code ret = radio->sendSMS(phone_number, sms_str);
-                if (ret != MTS_SUCCESS)
-                    logError("sending SMS failed");
-            }
+//
+//                sms_str = "SENSOR DATA:\n";
+//                sms_str += sms_json.serialize();
+//
+//                logDebug("sending SMS to %s:\r\n%s", phone_number.c_str(), sms_str.c_str());
+//                Code ret = radio->sendSMS(phone_number, sms_str);
+//                if (ret != MTS_SUCCESS)
+//                    logError("sending SMS failed");
+//            }
         }
 #endif
+
 #ifdef Web
         if (post_timer.read_ms() > post_interval_ms && do_cloud_post) {
     printf("in web\n\r");
-            if (radio->connect()) {
-                logDebug("posting sensor data");
-
-                HTTPClient http;
-                MbedJSONValue http_json_data;
-                std::string http_json_str;
-                std::string m2x_header = "X-M2X-KEY: " + m2x_api_key + "\r\n";
-                int ret;
-                char http_response_buf[256];
-                HTTPText http_response(http_response_buf, sizeof(http_response_buf));
-
-                // temp_c, temp_f, humidity, pressure, and moisture are all stream IDs for my device in M2X
-                // modify these to match your streams or give your streams the same name
-                http_json_data["values"]["temp_c"] = BDE0600_output;
-                http_json_data["values"]["UV"] = ML8511_output;
-                http_json_data["values"]["Ambient Light"] = RPR0521_ALS[0];
-                http_json_data["values"]["Prox"] = RPR0521_ALS[1];
-                http_json_str = http_json_data.serialize();
-
-                // add extra header with M2X API key
-                http.setHeader(m2x_header.c_str());
-
-                HTTPJson http_json((char*)  http_json_str.c_str());
-                ret = http.post(url.c_str(), http_json, &http_response);
-                if (ret != HTTP_OK)
-                    logError("posting data to cloud failed: [%d][%s]", ret, http_response_buf);
-                else
-                    logDebug("post result [%d][%s]", http.getHTTPResponseCode(), http_response_buf);
-
-                radio->disconnect();
-            } else {
-                logError("establishing PPP link failed");
-            }
+//            if (radio->connect()) {
+//                logDebug("posting sensor data");
+//
+//                HTTPClient http;
+//                MbedJSONValue http_json_data;
+//                std::string http_json_str;
+//                std::string m2x_header = "X-M2X-KEY: " + m2x_api_key + "\r\n";
+//                int ret;
+//                char http_response_buf[256];
+//                HTTPText http_response(http_response_buf, sizeof(http_response_buf));
+//
+//                // temp_c, temp_f, humidity, pressure, and moisture are all stream IDs for my device in M2X
+//                // modify these to match your streams or give your streams the same name
+//                http_json_data["values"]["temp_c"] = BDE0600_output;
+//                http_json_data["values"]["UV"] = ML8511_output;
+//                http_json_data["values"]["Ambient Light"] = RPR0521_ALS[0];
+//                http_json_data["values"]["Prox"] = RPR0521_ALS[1];
+//                http_json_str = http_json_data.serialize();
+//
+//                // add extra header with M2X API key
+//                http.setHeader(m2x_header.c_str());
+//
+//                HTTPJson http_json((char*)  http_json_str.c_str());
+//                ret = http.post(url.c_str(), http_json, &http_response);
+//                if (ret != HTTP_OK)
+//                    logError("posting data to cloud failed: [%d][%s]", ret, http_response_buf);
+//                else
+//                    logDebug("post result [%d][%s]", http.getHTTPResponseCode(), http_response_buf);
+//
+//                radio->disconnect();
+//            } else {
+//                logError("establishing PPP link failed");
+//            }
 
             post_timer.reset();
         }
 #endif
+
         wait_ms(10);
     }
 }
 
-// init functions
-bool init_mtsas()
-{
-    io = new MTSSerialFlowControl(RADIO_TX, RADIO_RX, RADIO_RTS, RADIO_CTS);
-    if (! io)
-        return false;
-
-    io->baud(115200);
-    radio = CellularFactory::create(io);
-    if (! radio)
-        return false;
-
-    Code ret = radio->setApn(apn);
-    if (ret != MTS_SUCCESS)
-        return false;
-
-    Transport::setTransport(radio);
-
-    return true;
-}
 
 
 // Sensor data acquisition functions
@@ -531,18 +571,18 @@
 }
 #endif
 
-#ifdef AnalogUV
-void ReadAnalogUV ()
-{
-    ML8511_UV_value = ML8511_UV.read_u16();
-    ML8511_output = (float)ML8511_UV_value * (float)0.000050354; //(value * (3.3V/65535))   //Note to self: when playing with this, a negative value is seen... Honestly, I think this has to do with my ADC converstion...
-    ML8511_output = (ML8511_output-(float)2.2)/((float)0.129) + 10;                           // Added +5 to the offset so when inside (aka, no UV, readings show 0)... this is the wrong approach... and the readings don't make sense... Fix this.
+//#ifdef AnalogUV       // analog pin A4 on Arduino connector is not connected to the mDot on the UDK.
+//void ReadAnalogUV ()
+//{
+//    ML8511_UV_value = ML8511_UV.read_u16();
+//    ML8511_output = (float)ML8511_UV_value * (float)0.000050354; //(value * (3.3V/65535))   //Note to self: when playing with this, a negative value is seen... Honestly, I think this has to do with my ADC converstion...
+//    ML8511_output = (ML8511_output-(float)2.2)/((float)0.129) + 10;                           // Added +5 to the offset so when inside (aka, no UV, readings show 0)... this is the wrong approach... and the readings don't make sense... Fix this.
 
 //    printf("ML8511 Analog UV Sensor Data:\r\n");
 //    printf(" UV = %.1f mW/cm2\r\n", ML8511_output);
 
-}
-#endif
+//}
+//#endif
 
 
 #ifdef HallSensor
@@ -753,10 +793,3 @@
     printf(" Pressure   = %0.2f hPa\r\n", BM1383[1]);
 
  **********************************************************************************/
-
-
-
-
-
-
-